/////precompiled////////
#include "precompiled.h"
////////////////////////


#include "prs_FrmPageControl.h"
//#include "prs_FrmDefTemplate.h"
using namespace prs;

// TNodeFrmPageControl ////////////////////////////////////////////////////////

//
frm::control::TPageControl *TNodeFrmPageControl::BuildControl(
  frm::control::TPanel *ParentControl
)
{
  frm::control::TPageControl *P = Control.GetValue();

  if (!P || &P->GetWindow() != &ParentControl->GetWindow()) {
    delete P; 
    P = new frm::control::TPageControl(ParentControl->GetWindow());
    Control.SetValue(P);
    
    ParentControl->AddChildLast(P,false);

    Geometry.Value.UnionWidthTo (P->GetGeometry());
    Geometry.Value.UnionHeightTo(P->GetGeometry());
  
    SetOrient();
  }
  return P;
}

//
void TNodeFrmPageControl::SetOrient()
{
  frm::TComponent *Ch1, *Ch2;
  switch ( Orient.GetValue() )
  {
    case TFrmPageOrient::Left:
      Ch1 = Control->GetFirstChild();
	    Ch2 = Control->GetLastChild();
	    Control->SwapChild( Ch1,Ch2 );
	  
	    Control->DirectChildren_Horz();
	   
	    Control->Buttons->
        Width_ChildrenMax().Height_ChildrenSum()
       .DirectChildren_Vert()
       .WAlignChildren_Begin().HAlignChildren_Center();
	   
	    Control->Client->
        Width_SiblingsRem().Height_Parent();
	  break;
  
    case TFrmPageOrient::Top:
      Ch1 = Control->GetFirstChild();
	    Ch2 = Control->GetLastChild();
	    Control->SwapChild( Ch1,Ch2 );

	    Control->DirectChildren_Vert();
	   
	    Control->Buttons->
        Width_ChildrenSum().Height_ChildrenMax()
       .DirectChildren_Horz()
       .WAlignChildren_Begin().HAlignChildren_Center();
	   
	    Control->Client->
        Width_Parent().Height_SiblingsRem();
	  break;

    case TFrmPageOrient::Right:
      Control->DirectChildren_Horz();
	   
	    Control->Buttons->
        Width_ChildrenMax().Height_ChildrenSum()
       .DirectChildren_Vert()
       .WAlignChildren_Begin().HAlignChildren_Center();
	   
	    Control->Client->
        Width_SiblingsRem().Height_Parent();
	  break;

    case TFrmPageOrient::Bottom:
      Control->DirectChildren_Vert();
	   
	    Control->Buttons->
        Width_ChildrenSum().Height_ChildrenMax()
       .DirectChildren_Horz()
       .WAlignChildren_Begin().HAlignChildren_Center();
	   
	    Control->Client->
        Width_Parent().Height_SiblingsRem();
	  break;
  }
}

// TRuleFrmPageControl ////////////////////////////////////////////////////////

//
TRuleFrmPageControl::TRuleFrmPageControl(
  snt::text::TContext &Context,
  svl::TVariant &VParentNode,
  TRuleFrmChildrenBase &RChildren,
  TRuleSetNodeIdOptionally &RSetNodeIdOptionally,
  TRuleSetAttrValue &RSetAttrValue,
  TRuleFrmGeom &RFrmGeom,
  TRuleSetStyle &RStyle
) 
:vParentNode(VParentNode)
,rGeometry(RFrmGeom)
{
  snt::text::TSequence T(Context);
  snt::text::TKeyword  K(Context);
  snt::text::TIdent    I(Context);
  snt::TFVoid F;
  TFuncNewNodeIntoAttrOldChildren FNewNode;
  snt::TReturn Return;

  this->Name(GetClassName()).Local(vParentNode)
  | K.New("pageControl") 
    & FNewNode.New(vParentNode,TNodeFrmPageControl()) 
    & RSetNodeIdOptionally.New() 
    & RAttr.New() 
    & Return.New()
  ;
  
  RAttr
  | T.New("(") 
    & RAttr1.New() 
    & RChildren.New() 
    & T.New(")") 
    & Return.New()
  | Return.New()
  ;

  RAttr1
  | AAttr1.New()
  ;
  AAttr1
  | RStyle.New()  
    & AAttr1.New()

  | RSetAttrValue.New(
      VParentNode,
      TRuleSetAttrValue::TAttrs()
       .Add(attrName_Orient), 
      RSetAttrValue.SetFuncValueIdent(this,&TRuleFrmPageControl::FSetParam)
    )
    & AAttr1.New()

  | F.New(this,&TRuleFrmPageControl::FSetGeometry) 
    & RFrmGeom.New() 
    & AAttr1.New()

  | Return.New()
  ;
}

//
bool TRuleFrmPageControl::FSetParam(TRuleSetAttrValue::TFuncValueIdentParams &Params) {
  return TNodeDefTemplate::AddLinkAttrByParamId(
    Params.Attr,TFrmPageOrientValue(),Params.Ident,Params.OutError
  );
}

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////


// TRuleFrmPage //////////////////////////////////////////////////////////

//
TRuleFrmPage::TRuleFrmPage(
  snt::text::TContext &Context,
  svl::TVariant &VParentNode,
  TRuleFrmChildrenBase &RChildren,
  TRuleSetNodeIdOptionally &RSetNodeIdOptionally,
  TRuleFrmGeom &RFrmGeom,
  TRuleSetStyle &RStyle
) 
:vParentNode(VParentNode)
,rGeometry(RFrmGeom)
{
  snt::text::TSequence T(Context);
  snt::text::TKeyword K(Context);
  snt::TFVoid F;
  TFuncNewNodeIntoAttrOldChildren FNewNode;
  snt::TReturn Return;

  this->Name(GetClassName()).Local(vParentNode)
  | K.New("page") & FNewNode.New(vParentNode,TNodeFrmPage()) 
    & RSetNodeIdOptionally.New() & RAttr.New() 
    & Return.New()
  ;
  
  RAttr
  | T.New("(") 
    & RAttr1.New() & RChildren.New() 
    & T.New(")") & Return.New()
  | Return.New()
  ;

  RAttr1
  | AAttr1.New()
  ;
  AAttr1
  | RStyle.New() & AAttr1.New()
  | F.New(this,&TRuleFrmPage::FSetGeometryPage) & RFrmGeom.New() & AAttr1.New()
  | RButton.New() & Return.New()
  | Return.New()
  ;

  // Button ////////////////
  RButton.Local(vParentNode)
  | K.New("pageButton") 
    & F.New(this,&TRuleFrmPage::FSetButton) 
    & RButtonAttr.New()  
    & Return.New()
  ;

  RButtonAttr
  | T.New("(") 
    & RButtonAttr1.New()
    & RChildren.New()
    & T.New(")")
    & Return.New()
  | Return.New()
  ;

  RButtonAttr1
  | AButtonAttr1.New()
  ;
  AButtonAttr1
  | RStyle.New()  & AButtonAttr1.New()
  | F.New(this,&TRuleFrmPage::FSetGeometryButton) & RFrmGeom.New() & AButtonAttr1.New()
  | Return.New()
  ;
}

//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
